"""
@File    :   service.py
@Time    :   2024/04/14 14:15:28
@Author  :   Qrj
@Email   :   923207736@qq.com
@description   :   系统配置相关业务逻辑
"""

from cashews import NOT_NONE
from sqlalchemy import select, update
from sqlalchemy.ext.asyncio import AsyncSession

from src.exceptions.custom_async_validator import generate_async_validator_exception
from src.utils.cashews import data_cache

from .models import SystemSettings
from .schemas.out import SystemSettingsCompleteOutSchema
from .schemas.validate import SystemSettingsUpdateValidateSchema


class SystemSettingsService:
    """系统配置业务逻辑类"""

    @data_cache(
        ttl="30m",
        key="tenant_settings#id:{tenant_id}",
        tags=["tenant_settings#id", "tenant_settings#id:{tenant_id}"],
        condition=NOT_NONE,
    )
    @staticmethod
    async def get_system_settings_use_tenant_id(
        db_session: AsyncSession,
        tenant_id: int,
        raise_not_exists_exception: bool = True,
    ) -> SystemSettingsCompleteOutSchema | None:
        """获取指定租户的系统配置信息

        Args:
            db_session (AsyncSession): 数据库连接池
            tenant_id (int): 租户ID
            raise_not_exists_exception (bool, optional): 未找到时是否报错

        Returns:
            RoleCompleteOutSchema: 租户的系统配置信息
        """
        search_sql = select(
            *SystemSettingsCompleteOutSchema.convert_to_sql_model_field(SystemSettings)
        ).where(SystemSettings.tenant_id == tenant_id)
        async with db_session.begin():
            search_res = await db_session.execute(search_sql)
        result = search_res.mappings().first()
        if result is not None:
            # 转换成pydantic的序列化模型
            result = SystemSettingsCompleteOutSchema.model_validate(result)
            return result
        elif result is None and raise_not_exists_exception:
            # 未找到则报错
            raise generate_async_validator_exception("id", "指定租户的系统配置不存在")
        else:
            return result

    @staticmethod
    @data_cache.transaction()
    async def update_system_settings(
        db_session: AsyncSession,
        tenant_id: int,
        update_schema: SystemSettingsUpdateValidateSchema,
        updater_username: str = "",
    ):
        """修改角色信息

        Args:
            db_session (AsyncSession): 数据库连接池
            tenant_id (int): 租户ID
            update_schema (SystemSettingsUpdateValidateSchema): 修改操作所需的数据
            updater_username (str, optional):修改者用户名
        """
        # 检查需修改的sql实例是否存在是否存在
        await SystemSettingsService.get_system_settings_use_tenant_id(
            db_session, tenant_id
        )
        # 构建修改所需的数据(排除未设置的值和id)
        update_schema_data = update_schema.model_dump(exclude_unset=True)
        if update_schema_data:
            # 修改sql
            update_sql = (
                update(SystemSettings)
                .values(**update_schema_data, updater_username=updater_username)
                .where(SystemSettings.tenant_id == tenant_id)
            )
            # 修改操作
            async with db_session.begin():
                # 修改sql数据
                await db_session.execute(update_sql)
                # 清空相关缓存标签
                await data_cache.delete_tags(f"tenant_settings#id:{tenant_id}")
